﻿#pragma once

//贪吃蛇小游戏的完全实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <Windows.h>
#include <locale.h>


//定义的一个结点的坐标
typedef struct CoordinateOfSnackNode
{
	short x;
	short y;
}NodeCoord;

//定义一个蛇的结点————由链表实现
typedef struct SnackNode
{
	NodeCoord coord;
	struct SnakcNode* next;
}SnackNode, * pSnackNode;

//蛇的移动方向
enum DIRECTION
{
	UP,
	DOWN,
	LEFT,
	RIGHT
};

//蛇的状态
enum STATE
{
	OK,
	END_NORMAL,
	HIT_BYSELF,
	HIT_BYWALL
};

//定义一整条蛇————包含如下信息
typedef struct Snack
{
	//蛇头
	pSnackNode _SnackHead;
	//蛇的移动方向
	enum DIRECTION _dire;
	//每走一步的休眠时间
	int _sleeptime;
	//蛇的状态
	enum STATE _state;
	//食物
	pSnackNode _food;
	//一个食物的分数
	int _foodweight;
	//当前获得的总分数
	int _score;
}Snack, * pSnack;


//游戏开始
void GameStart(pSnack ps);

//设置光标位置
void SetPos(short x, short y);

//隐藏光标
void HideCursorInfo();

//调整好控制台的大小和名称
void AdjustConsole();

//打印欢迎界面
void Welcome();

//打印游戏说明界面
void PrintHelp();

//创造游戏地图
void CreateMap(pSnack ps);

//蛇头的初位置
#define POS_X 24
#define POS_Y 5

//初始化蛇身
void SnackInit(pSnack ps);

//创建蛇的一个结点
pSnackNode BuySnackNode(NodeCoord coord);

//打印蛇
//蛇头
#define HEAD L'■'
//蛇身
#define BODY L'●'
void ShowSnack(pSnack ps);

//创造一个食物
#define FOOD L'★'
void CreateFood(pSnack ps);

//游戏运行
void GameRun(pSnack ps);

//定义一个宏，用于确定按键是否被按，按后则返回1，否则返回0；
#define KEY_PRESS(VK) (GetAsyncKeyState(VK) & 0x1)

//显示得分情况
void ShowScore(pSnack ps);

//空格space暂停
void SleepForever();

//移动一步
void SnackMove(pSnack ps);

//下一个头结点
pSnackNode NextNode(pSnack ps);

//判断下一个结点是否是食物
bool IsFood(pSnack ps, pSnackNode nextnode);

//吃掉食物
void EatFood(pSnack ps);

//判断是否撞墙
bool IsBeHitedByWall(pSnackNode nextnode);

//判断是否撞到自己
bool IsBeHitedBySelf(pSnack ps, pSnackNode nextnode);

//正常移动
void Move(pSnack ps, pSnackNode nextnode);

//游戏结束
void GameOver(pSnack ps);